//#include "gpiogpio.h"
#include <stdlib.h>
#include <glib-object.h>
#include <stdbool.h>
#define GPIO_GPIO_TYPE (gpio_gpio_get_type())
G_DECLARE_FINAL_TYPE(GpioGpio, gpio_gpio, GPIO, GPIO, GObject)
typedef struct _GpioGpio {
  GObject parent_instance;

  gchar *class;

  gint64 id;
  gint64 parentID;
  gint status;
  gint enable;

  gint port;
  gint targetValue;
  gint oldValue;

  gint type;
  gint value;
  gint chipNum;
  gint lineOffset;

  gchar *name;
  gchar *ip;
  
  gpointer userData;
  gpointer connection;
  gpointer chip;
  gpointer line;

  gpointer init, stop, run, private;

  GObject *next;
  GObject *son;//part
  GObject *parent;
} GpioGpio;
enum {
  PROP_0,
  PROP_CLASS,
  PROP_ID, PROP_PARENT_ID,
  PROP_STATUS, PROP_ENABLE,
  PROP_PORT, PROP_TARGET_VALUE, PROP_OLD_VALUE,
  PROP_TYPE, PROP_VALUE, PROP_CHIP_NUM, PROP_LINE_OFFSET,
  PROP_NAME,
  PROP_IP,
  PROP_USER_DATA, PROP_CONNECTION, PROP_CHIP, PROP_LINE,
  PROP_INIT, PROP_STOP, PROP_RUN, PROP_PRIVATE,
  PROP_NEXT, PROP_SON, PROP_PARENT,
  N_PROPERTIES };

static GParamSpec *properties[N_PROPERTIES] = { NULL, };

G_DEFINE_TYPE(GpioGpio, gpio_gpio, G_TYPE_OBJECT)
//int64
static void gpio_gpio_set_id(GpioGpio *obj, gint64    value)
{
  if (obj->id != value)
    {
      obj->id = value;

      g_assert(properties[PROP_ID] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_ID]);
    }
}
static void gpio_gpio_set_parentID(GpioGpio *obj, gint64    value)
{
  if (obj->parentID != value)
    {
      obj->parentID = value;

      g_assert(properties[PROP_PARENT_ID] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_PARENT_ID]);
    }
}
static void gpio_gpio_set_targetValue(GpioGpio *obj, gint value)
{
  if (obj->targetValue != value)
    {
      obj->targetValue = value;
      g_assert(properties[PROP_TARGET_VALUE] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj),
          properties[PROP_TARGET_VALUE]);
    }
}
static void gpio_gpio_set_port(GpioGpio *obj, gint value)
{
  if (obj->port != value)
    {
      obj->port = value;
      g_assert(properties[PROP_PORT] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_PORT]);
    }
}
static void gpio_gpio_set_type(GpioGpio *obj, gint    value)
{
  if (obj->type != value)
    {
      obj->type = value;
      g_assert(properties[PROP_TYPE] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_TYPE]);
    }
}
static void gpio_gpio_set_value(GpioGpio *obj, gint    value)
{
  if (obj->value != value)
    {
      obj->value = value;
      g_assert(properties[PROP_VALUE] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_VALUE]);
    }
}
static void gpio_gpio_set_chipNum(GpioGpio *obj, gint    value)
{
  if (obj->chipNum != value)
    {
      obj->chipNum = value;
      g_assert(properties[PROP_CHIP_NUM] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_CHIP_NUM]);
    }
}
static void gpio_gpio_set_lineOffset(GpioGpio *obj, gint    value)
{
  if (obj->lineOffset != value)
    {
      obj->lineOffset = value;
      g_assert(properties[PROP_LINE_OFFSET] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_LINE_OFFSET]);
    }
}
//char
static void gpio_gpio_set_ip(GpioGpio  *obj, const gchar *value)
{
  if (g_strcmp0(obj->ip, value) != 0)
    {
      g_free(obj->ip);
      obj->ip = g_strdup(value);
      g_assert(properties[PROP_IP] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_IP]);
    }
}
static void gpio_gpio_set_name(GpioGpio  *obj, const gchar *name)
{
  if (g_strcmp0(obj->name, name) != 0)
    {
      g_free(obj->name);
      obj->name = g_strdup(name);
      g_assert(properties[PROP_NAME] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_NAME]);
    }
}
static void gpio_gpio_set_class(GpioGpio  *obj, const gchar *value)
{
  if (g_strcmp0(obj->class, value) != 0)
    {
      g_free(obj->class);
      obj->class = g_strdup(value);

      g_assert(properties[PROP_CLASS] != NULL);
      g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_CLASS]);
    }
}
static void gpio_gpio_set_user_data(GpioGpio  *obj, gpointer value)
{
    obj->userData = value;
}
static void gpio_gpio_set_connection(GpioGpio  *obj, gpointer value)
{
    obj->connection = value;
}
static void gpio_gpio_set_chip(GpioGpio  *obj, gpointer value)
{
    obj->chip = value;
}
static void gpio_gpio_set_line(GpioGpio  *obj, gpointer value)
{
    obj->line = value;
}
static void gpio_gpio_set_init(GpioGpio  *obj, gpointer value)
{
    obj->init = value;
}
static void gpio_gpio_set_stop(GpioGpio  *obj, gpointer value)
{
    obj->stop = value;
}
static void gpio_gpio_set_run(GpioGpio  *obj, gpointer value)
{
    obj->run = value;
}
static void gpio_gpio_set_private(GpioGpio  *obj, gpointer value)
{
    obj->private = value;
}
//object
static void gpio_gpio_set_next(GpioGpio  *obj, gpointer next)
{
    obj->next = next;
}

static void gpio_gpio_set_son(GpioGpio  *obj, gpointer son)
{
    obj->son = son;
}
static void gpio_gpio_set_parent(GpioGpio  *obj, gpointer value)
{
    obj->parent = value;
}

static void
gpio_gpio_finalize(GObject *gobject)
{
  GpioGpio *self = (GpioGpio *) gobject;

  if (self->next)
    g_object_unref(self->next);
  if (self->son)
    g_object_unref(self->son);
  if (self->ip)
    g_free(self->ip);
  if (self->name)
    g_free(self->name);
  if (self->class)
    g_free(self->class);

  G_OBJECT_CLASS(gpio_gpio_parent_class)->finalize(gobject);
}

static void
gpio_gpio_set_property(GObject *gobject,
                          guint prop_id,
                          const GValue *value,
                          GParamSpec *pspec)
{
  GpioGpio *tobj = (GpioGpio *) gobject;

  g_assert_cmpint(prop_id, !=, 0);
  g_assert_cmpint(prop_id, !=, N_PROPERTIES);
  g_assert(pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      gpio_gpio_set_id(tobj, g_value_get_int64(value));
      break;
    case PROP_PARENT_ID:
      gpio_gpio_set_parentID(tobj, g_value_get_int64(value));
      break;

    case PROP_STATUS:
      tobj->status = g_value_get_int(value);
      break;
    case PROP_ENABLE:
      tobj->enable = g_value_get_int(value);
      break;

    case PROP_TARGET_VALUE:
      gpio_gpio_set_targetValue(tobj, g_value_get_int(value));
      break;
    case PROP_OLD_VALUE:
      tobj->oldValue = g_value_get_int(value);
      break;
    case PROP_PORT:
      gpio_gpio_set_port(tobj, g_value_get_int(value));
      break;
    case PROP_TYPE:
      gpio_gpio_set_type(tobj, g_value_get_int(value));
      break;
    case PROP_VALUE:
      gpio_gpio_set_value(tobj, g_value_get_int(value));
      break;
    case PROP_CHIP_NUM:
      gpio_gpio_set_chipNum(tobj, g_value_get_int(value));
      break;
    case PROP_LINE_OFFSET:
      gpio_gpio_set_lineOffset(tobj, g_value_get_int(value));
      break;

    case PROP_IP:
      gpio_gpio_set_ip(tobj, g_value_get_string(value));
      break;
    case PROP_NAME:
      gpio_gpio_set_name(tobj, g_value_get_string(value));
      break;
    case PROP_CLASS:
      gpio_gpio_set_class(tobj, g_value_get_string(value));
      break;
    case PROP_USER_DATA:
      gpio_gpio_set_user_data(tobj, g_value_get_pointer(value));
      break;
    case PROP_CONNECTION:
      gpio_gpio_set_connection(tobj, g_value_get_pointer(value));
      break;
    case PROP_CHIP:
      gpio_gpio_set_chip(tobj, g_value_get_pointer(value));
      break;
    case PROP_LINE:
      gpio_gpio_set_line(tobj, g_value_get_pointer(value));
      break;

    case PROP_INIT:
      gpio_gpio_set_init(tobj, g_value_get_pointer(value));
      break;
    case PROP_STOP:
      gpio_gpio_set_stop(tobj, g_value_get_pointer(value));
      break;
    case PROP_RUN:
      gpio_gpio_set_run(tobj, g_value_get_pointer(value));
      break;
    case PROP_PRIVATE:
      gpio_gpio_set_private(tobj, g_value_get_pointer(value));
      break;

    case PROP_SON:
      gpio_gpio_set_son(tobj, g_value_get_pointer(value));
      break;
    case PROP_NEXT:
      gpio_gpio_set_next(tobj, g_value_get_pointer(value));
      break;
    case PROP_PARENT:
      gpio_gpio_set_parent(tobj, g_value_get_pointer(value));
      break;

    default:
      g_assert_not_reached();
    }
}

static void
gpio_gpio_get_property(GObject *gobject,
                          guint prop_id,
                          GValue *value,
                          GParamSpec *pspec)
{
  GpioGpio *tobj = (GpioGpio *) gobject;

  g_assert_cmpint(prop_id, !=, 0);
  g_assert_cmpint(prop_id, !=, N_PROPERTIES);
  g_assert(pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      g_value_set_int64(value, tobj->id);
      break;
    case PROP_PARENT_ID:
      g_value_set_int64(value, tobj->parentID);
      break;

    case PROP_STATUS:
      g_value_set_int(value, tobj->status);
      break;
    case PROP_ENABLE:
      g_value_set_int(value, tobj->enable);
      break;

    case PROP_TARGET_VALUE:
      g_value_set_int(value, tobj->targetValue);
      break;
    case PROP_OLD_VALUE:
      g_value_set_int(value, tobj->oldValue);
      break;
    case PROP_PORT:
      g_value_set_int(value, tobj->port);
      break;
    case PROP_TYPE:
      g_value_set_int(value, tobj->type);
      break;
    case PROP_VALUE:
      g_value_set_int(value, tobj->value);
      break;
    case PROP_CHIP_NUM:
      g_value_set_int(value, tobj->chipNum);
      break;
    case PROP_LINE_OFFSET:
      g_value_set_int(value, tobj->lineOffset);
      break;

    case PROP_IP:
      g_value_set_string(value, tobj->ip);
      break;
    case PROP_NAME:
      g_value_set_string(value, tobj->name);
      break;
    case PROP_CLASS:
      g_value_set_string(value, tobj->class);
      break;
    case PROP_USER_DATA:
      g_value_set_pointer(value, tobj->userData);
      break;
    case PROP_CONNECTION:
      g_value_set_pointer(value, tobj->connection);
      break;
    case PROP_CHIP:
      g_value_set_pointer(value, tobj->chip);
      break;
    case PROP_LINE:
      g_value_set_pointer(value, tobj->line);
      break;

    case PROP_INIT:
      g_value_set_pointer(value, tobj->init);
      break;
    case PROP_STOP:
      g_value_set_pointer(value, tobj->stop);
      break;
    case PROP_RUN:
      g_value_set_pointer(value, tobj->run);
      break;
    case PROP_PRIVATE:
      g_value_set_pointer(value, tobj->private);
      break;

    case PROP_SON:
      g_value_set_pointer(value, tobj->son);
      break;
    case PROP_NEXT:
      g_value_set_pointer(value, tobj->next);
      break;
    case PROP_PARENT:
      g_value_set_pointer(value, tobj->parent);
      break;
    default:
      g_error("%d\n", prop_id);
      g_assert_not_reached();
    }
}

static void
gpio_gpio_class_init(GpioGpioClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

  properties[PROP_ID] = g_param_spec_int64("id", "id", "Id",
      G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE);
  properties[PROP_PARENT_ID] = g_param_spec_int64(
      "parentID", "parentID", "ParentId",
      -1, G_MAXINT64, 0, G_PARAM_READWRITE);
  properties[PROP_STATUS] = g_param_spec_int(
      "status", "Status", "STATUS",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_ENABLE] = g_param_spec_int(
      "enable", "Enable", "ENABLE",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_TYPE] = g_param_spec_int("type", "type", "type",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);

  properties[PROP_TARGET_VALUE] = g_param_spec_int(
      "targetValue", "TargetValue", "TARGETVALUE",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_OLD_VALUE] = g_param_spec_int(
      "oldValue", "OldValue", "OLDVALUE",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_PORT] = g_param_spec_int("port", "port", "port",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_VALUE] = g_param_spec_int("value", "Value", "VALUE",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_CHIP_NUM] = g_param_spec_int("chipNum", "ChipNum", "CHIPNUM",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_LINE_OFFSET] = g_param_spec_int(
      "lineOffset", "LineOffset", "LINEOFFSET",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);

  properties[PROP_IP] = g_param_spec_string("ip", "Ip", "IP",
      NULL, G_PARAM_READWRITE);
  properties[PROP_NAME] = g_param_spec_string("name", "Name", "NAME",
      NULL, G_PARAM_READWRITE);
  properties[PROP_CLASS] = g_param_spec_string("class", "Class", "CLASS",
      NULL, G_PARAM_READWRITE);
  properties[PROP_USER_DATA] = g_param_spec_pointer(
      "userData", "UserData", "USERDATA",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_CONNECTION] = g_param_spec_pointer(
      "connection", "Connection", "CONNECTION",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_CHIP] = g_param_spec_pointer("chip", "Chip", "CHIP",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_LINE] = g_param_spec_pointer("line", "Line", "LINE",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_INIT] = g_param_spec_pointer("init", "Init", "INIT",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_STOP] = g_param_spec_pointer("stop", "Stop", "STOP",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_RUN] = g_param_spec_pointer("run", "Run", "RUN",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_PRIVATE] = g_param_spec_pointer(
      "private", "Private", "PRIVATE",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  properties[PROP_SON] = g_param_spec_pointer("son", "son", "son",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_NEXT] = g_param_spec_pointer("next", "next", "next",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_PARENT] = g_param_spec_pointer("parent", "Parent", "PARENT",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  gobject_class->set_property = gpio_gpio_set_property;
  gobject_class->get_property = gpio_gpio_get_property;
  gobject_class->finalize = gpio_gpio_finalize;

  g_object_class_install_properties(gobject_class, N_PROPERTIES, properties);
}

static void gpio_gpio_init(GpioGpio *self)
{
//  self->status = FALSE;
}

GpioGpio *gpio_gpio_new(void)
{
  return g_object_new(GPIO_GPIO_TYPE, NULL);
}
